import os

########################################################################
class USBSCSIDevice():
    """Gives USB and SCSI device informations.
       Provides basic operations (mount, umount).
       Note that almost all infos are created during initialization.
       Create new instance to refresh info.
       Operands (mount/umount/isMounted/getMountPoint) works live."""

    #----------------------------------------------------------------------   
    def __init__(self, usbVendor, usbProduct, serial):
        """Constructor. Use correct args or wait in deadlock :P"""
        self.usbVendor = usbVendor
        self.usbProduct = usbProduct
        self.serial = serial

        #scsi proc
        command = "grep -l " + str(self.serial) + " /proc/scsi/usb-storage/*"
        self.scsiFile = os.popen(command).readline().rstrip("\n")
        command = "grep Host " + self.scsiFile + "|sed -e 's/ *Host //' -e 's/: usb-storage//'"
        self.scsiHost = os.popen(command).readline().rstrip("\n")
        command = "grep Vendor " + self.scsiFile + "|sed -e 's/ *Vendor: //'"
        self.scsiVendor = os.popen(command).readline().rstrip("\n")
        command = "grep Product " + self.scsiFile + "|sed -e 's/ *Product: //'"
        self.scsiProduct = os.popen(command).readline().rstrip("\n")            

        #scsi sg_scan
        command = "sg_scan |grep " + self.scsiHost + "|sed -e 's/:.*//'"
        self.scsiDev = os.popen(command).readline().rstrip("\n")

        #scsi sg_map
        command = "sg_map |grep " + self.scsiDev + "| cut -d\  -f3"
        self.devMap = os.popen(command).readline().rstrip("\n")

        #device size
        command = "grep " + self.devMap.split("/")[-1] + "$ /proc/partitions"
        self.devSize = os.popen(command).readline().rstrip("\n").split()[2]


    def __str__(self):
	return self.scsiVendor + " " + self.scsiProduct +  " (" + str(int(self.devSize)/1024) + "MB) available at " + self.devMap + " with id " + self.serial

    #----------------------------------------------------------------------
    # getters
    #----------------------------------------------------------------------
    def getUSBVendor(self):
        """Returnes USB device vendor"""
        return self.usbVendor

    #----------------------------------------------------------------------
    def getUSBProduct(self):
        """Returnes USB device product"""
        return self.usbProduct

    #----------------------------------------------------------------------
    def getSerial(self):
        """Returnes device serial"""
        return self.serial

    #----------------------------------------------------------------------
    def getSCSIVendor(self):
        """Returnes SCSI device vendor"""
        return self.scsiVendor

    #----------------------------------------------------------------------
    def getSCSIProduct(self):
        """Returnes SCSI device product"""
        return self.scsiProduct

    #----------------------------------------------------------------------
    def getDeviceMap(self):
        """Returnes device's /dev/ path"""
        return self.devMap

    #----------------------------------------------------------------------
    def getDeviceSize(self):
        """Returns device's size in kB"""
        return self.devSize

    #----------------------------------------------------------------------
    def getBackupSize(self):
	return self.backupSize    

    #----------------------------------------------------------------------
    def setBackupSize(self, backupSize):
	self.backupSize = backupSize
    
    #----------------------------------------------------------------------
    def isMounted(self):
        """Returns True if mounted"""
        command = "mount | grep " + self.devMap.split('/')[-1] + " | wc -l"
        mounted = int(os.popen(command).readline().rstrip("\n"))
        if mounted == 1:
            return True
        else:
            return False

    #----------------------------------------------------------------------
    def getMountPoint(self):
        """Returns mount point or None if not mounted"""

        if not self.isMounted():
            return None
        #else:
        command = "mount | grep " + self.devMap.split('/')[-1] + " | cut -d\  -f3"
        mountPoint = os.popen(command).readline().rstrip("\n")

        return mountPoint

    #----------------------------------------------------------------------
    # operands
    #----------------------------------------------------------------------
    def mount(self, dir):
        """Mounts device to given dir. Dir has to exist!"""
        if self.isMounted():
            raise Exception("Device is mounted exception!")
        #else:
        command = "mount " + self.devMap + " " + dir
        os.popen(command)

    def umount(self):
        """Unmounts device"""
        if not self.isMounted():
            raise Exception("Device not mounted exception!")
        #else:
        command = "umount " + self.devMap
        os.popen(command)

    def checkDevice(self):
        """Looks for special eBackuper file. This determines whether we
        can use device"""
        return os.path.exists(self.getMountPoint() + "/.ebackuper")

    def prepareDevice(self):
	"""Creates special eBackuper file. This determines whether we
        can use device"""
        os.popen("touch " + self.getMountPoint() + "/.ebackuper")
